/*---------------------------------------
   BEIZER.C -- Bezier Splines Demo
               (c) Charles Petzold, 1996
  ---------------------------------------*/

//#include <windows.h>
#include "open_save.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static char szAppName[] = "Painter" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASSEX  wndclass ;

     wndclass.cbSize        = sizeof (wndclass) ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;

     RegisterClassEx (&wndclass) ;

     hwnd = CreateWindow (szAppName, "PAINTER",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;

     while (GetMessage (&msg, NULL, 0, 0))
		  {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
          }
     return msg.wParam ;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
     static POINT apt[4] ;
     int          cxClient, cyClient ;
     static int x = 0, y = 0, xt = 0, yt= 0;
	 static int isPressed = 0;

	 static RECT  r;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;
	 DWORD dwStyle;
	 int EDITID[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
	 HPEN hPen;
	
	 static int flag = 0;
	 static shape *p;
	 static  Stack<shape *> undo,redo,*temp;

	
	 

	 static HWND hwndButton[10];//declaration of Button array.
	 static HWND hwndList;//declaration of a List Box.

	 

	 int i,j;

	 char *buttonStr1[10] = {"RECT","ELLIPSE","SQUARE","CIRCLE","LINE"};//array of a string pointers(contains the name of the buttons)
	 char *buttonStr2[10] = {"OPEN","SAVE","REDO","UNDO"};//array of a string pointers(contains the name of the buttons)

     switch (iMsg)
          {

		  case WM_CREATE :

			   hdc = GetDC (hwnd) ;
               SelectObject(hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;//sellect a font for the program.
               GetTextMetrics (hdc, &tm) ;//fill the specified buffer with the sellected font.
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;
               SendMessage(hwnd,WM_SIZE,0,0);

			  dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | 
								WS_BORDER | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL | 
								ES_AUTOHSCROLL | ES_AUTOVSCROLL;  

			  for(i=0,j=0;i<5;i++,j+=125)
				{
					hwndButton[i] = CreateWindow (
								"button", 
								buttonStr1[i],
								WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
								100 + j,
								r.bottom - 50,
								10 * cxChar, 
								7 * cyChar / 4,
								hwnd, 
								(HMENU)(EDITID[i]),
								((LPCREATESTRUCT) lParam) -> hInstance, 
								NULL) ;
				} 

			  for(i=0,j=0;i<4;i++,j+=100)
				{
					hwndButton[i] = CreateWindow (
								"button", 
								buttonStr2[i],
								WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
								cxChar,
								35 + j,
								10 * cxChar, 
								7 * cyChar / 4,
								hwnd, 
								(HMENU)(EDITID[5+i]),
								((LPCREATESTRUCT) lParam) -> hInstance, 
								NULL) ;
				} 

			   hwndList = CreateWindow ("listbox", NULL,                       //listbox
                            WS_CHILD | WS_VISIBLE | LBS_STANDARD,
							r.right - 200, r.top + 20, 190, 250,
                            hwnd, (HMENU)(EDITID[11]),
                            (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ;
			
 

			  return 0;

          case WM_SIZE:

			   GetClientRect(hwnd,&r);//insert the window sizes to r
              
               return 0 ;

		  case WM_COMMAND :
			   switch(LOWORD(wParam))
			   {
			  
			  

					case 0: //RECT
						
							flag = 1;
							p = new rect;
				
					     break;

					case 1: //ELLIPSE

							flag = 1;
							p = new ellipse;
							
					     break;

					case 2: //SQUARE 

							flag = 1;
							p = new square;
					
					     break;

					 case 3: //CIRCLE 

							flag = 1;
							p = new circle;
							
					     break;

					 case 4: //LINE 
						
							flag = 1;
							p = new line;

						 break;

					 case 5: //OPEN 

								OpenFromFile(hwnd,redo,undo);
						
						 break;

					 case 6: //SAVE
									
							SaveToFile(redo,hwnd);

						 break;

					 case 7: //REDO 

						 if(!undo.Empty())
						 {
							 p = undo.Pop();
							 redo.Push(p);
							 p->Draw(hwnd);
						 }

					
						 break;

					 case 8: //UNDO

						 if(!redo.Empty())
						 {
							 p = redo.Pop();
							 undo.Push(p);
							 p->Hide(hwnd);
						 }
					
						 break;

					 case 9: 

						 
				
						 break;
			   }

			  return 0;

		   case WM_LBUTTONDOWN:
			
			   if(flag)
			   {
				 isPressed=1;
				 x = xt = LOWORD(lParam);
				 y = yt = HIWORD(lParam);
				 if(x<100)
					 x=100;
				 else if(x>700)
					 x=700;
				 if(y>600)
					 y=600;
				 p->SetPos(point(x,y));
			   }

				 return 0;

           case WM_MOUSEMOVE:

               if(isPressed && flag)
			   {
				    p->Hide(hwnd);
					xt = LOWORD(lParam);
					yt = HIWORD(lParam);
					p->Draw(hwnd,xt,yt);
			   }

               return 0 ;

		   case WM_LBUTTONUP:
		 
				isPressed=0;
				if(flag)
				{
					redo.Push(p);
					SendMessage (hwndList, LB_ADDSTRING, 0,(long) "SHAPE SAVED !!!");
				}
				flag = 0;

			   break;

           case WM_PAINT:

	           hdc = BeginPaint (hwnd, &ps) ;
					
	           EndPaint (hwnd,&ps) ;
               return 0 ;
			   

          case WM_DESTROY:

               PostQuitMessage (0) ;
               return 0 ;
	}

     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}


